package cn.ac.iie.bdb_to_mongo.mongohandler;

import cn.ac.iie.bdb_to_mongo.BdbMain;
import cn.ac.iie.bdb_to_mongo.commons.Constants;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.TimerTask;

/**
 * @auther Fighter Created on 2016/12/2.
 */
public class UpdateMongoTask extends TimerTask {

    private final Logger log = LoggerFactory.getLogger(UpdateMongoTask.class);
    public static MongoHelper mongoHelper = null;
    public static MongoHelper mongoHelper1 = null;

    //连接mongo
    public UpdateMongoTask() {
        try {
            //旧表
            mongoHelper = new MongoHelper(
                    BdbMain.configuration.getString(Constants.MONGO_HOSTS).split(";"),
                    BdbMain.configuration.getString(Constants.MONGO_DB),
                    BdbMain.configuration.getString(Constants.MONGO_TABLE),
                    BdbMain.configuration.getString(Constants.MONGO_USER),
                    BdbMain.configuration.getString(Constants.MONGO_PASSWD));
            //新表
            mongoHelper1 = new MongoHelper(
                    BdbMain.configuration.getString(Constants.MONGO_HOSTS1).split(";"),
                    BdbMain.configuration.getString(Constants.MONGO_DB1),
                    BdbMain.configuration.getString(Constants.MONGO_TABLE1),
                    BdbMain.configuration.getString(Constants.MONGO_USER1),
                    BdbMain.configuration.getString(Constants.MONGO_PASSWD1));

        } catch (Exception e) {
            e.printStackTrace();
            log.error("mongo connection error");
        }
    }

    /**
     * 该线程只是为了产生子线程，子线程负责具体的更新mongo操作
     */
    @Override
    public void run() {
        if (BdbMain.updateMongoFlag.get()) {
            log.info("UpdateMongoTask is running...");
            //先修改写bdb标志量，阻止写bdb操作
            BdbMain.writeFlag.set(false);
            BdbMain.updateMongoFlag.set(false);
            BdbMain.testDB.sync();//落盘
            log.info("bdb size is:" + BdbMain.testDB.size());
//            System.exit(1);

            long bdbSize = BdbMain.testDB.size();

            int updateThreadNum = BdbMain.configuration.getInt(Constants.UPDATE_MONGO_THREAD_NUM);
            long sliceLen = bdbSize / updateThreadNum;

            if (bdbSize > updateThreadNum) {

                /*for (int i = 0; i < updateThreadNum; i++) {
                    Thread t = new Thread(new UpdateTask(i, sliceLen, i == updateThreadNum - 1), "No." + i + " update thread");
                    try {
                        t.start();
                        t.join();//加入到当前线程中，这样全部插入完毕方可修改writeFlag
                    } catch (InterruptedException e) {
                        log.error("join thread error" + ExceptionUtils.getFullStackTrace(e));
                    }
                }*/

                List<Thread> threadList = new ArrayList<>();
                for (int i = 0; i < updateThreadNum; i++) {
                    Thread t = new Thread(new UpdateTask(i, sliceLen, i == updateThreadNum - 1), "No." + i + " update thread");
                    t.start();
                    threadList.add(t);
                }

                for (int i = 0; i < threadList.size(); i++) {
                    try {
                        threadList.get(i).join();//加入到当前线程中，这样全部插入完毕方可修改writeFlag
                    } catch (InterruptedException e) {
                        log.error("thread join error!");
                    }
                }

            } else {
                Thread t = new Thread(new UpdateTask(0, sliceLen, true), "No." + 0 + " update thread");
                try {
                    t.start();
                    t.join();//加入到当前线程中，这样全部插入完毕方可修改writeFlag
                } catch (InterruptedException e) {
                    log.error("join thread error" + ExceptionUtils.getFullStackTrace(e));
                }
            }

//            mongoHelper.close();//关闭mongo连接
//            mongoHelper1.close();
//            long numDiscarded = BdbMain.testDB.bulkDelete();//内部先关闭db，再批量删除，再打开db
            long numDiscarded = BdbMain.testDB.deleteRecords();
            log.info("delete bdb " + numDiscarded + " records");
            BdbMain.testDB.sync();//落盘
            BdbMain.updateMongoFlag.set(true);//正常结束，下次可以执行新任务
            log.info("UpdateMongoTask is over");
            BdbMain.writeFlag.set(true);//开启写bdb

        }
    }
}